{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "64d5f8ff",
   "metadata": {},
   "source": [
    "# 一、用户管理功能"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4389258f",
   "metadata": {},
   "source": [
    "因为需要加入手机验证码登录的功能，我选择了自己写一个模型来实现。当然还是继承AbstractUser。\n",
    "下面来看看模型代码。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "70134c7e",
   "metadata": {},
   "outputs": [
    {
     "ename": "ImproperlyConfigured",
     "evalue": "Requested setting INSTALLED_APPS, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mImproperlyConfigured\u001b[0m                      Traceback (most recent call last)",
      "\u001b[0;32m/var/folders/wk/41sn44kx3_dc1n5395nfzdrr0000gn/T/ipykernel_21407/2200180560.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mfrom\u001b[0m \u001b[0mdjango\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcontrib\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mauth\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmodels\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mAbstractUser\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      2\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mdjango\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdb\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mmodels\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      3\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0muuid\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      5\u001b[0m \u001b[0;31m# Create your models here.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/.virtualenvs/universe/lib/python3.9/site-packages/django/contrib/auth/models.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mdjango\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mapps\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mapps\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      2\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mdjango\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcontrib\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mauth\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0;32mfrom\u001b[0m \u001b[0mdjango\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcontrib\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mauth\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbase_user\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mAbstractBaseUser\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mBaseUserManager\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      4\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mdjango\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcontrib\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mauth\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mhashers\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mmake_password\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      5\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mdjango\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcontrib\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcontenttypes\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmodels\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mContentType\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/.virtualenvs/universe/lib/python3.9/site-packages/django/contrib/auth/base_user.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m     46\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     47\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 48\u001b[0;31m \u001b[0;32mclass\u001b[0m \u001b[0mAbstractBaseUser\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmodels\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mModel\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     49\u001b[0m     \u001b[0mpassword\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmodels\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mCharField\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0m_\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'password'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmax_length\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m128\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     50\u001b[0m     \u001b[0mlast_login\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmodels\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mDateTimeField\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0m_\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'last login'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mblank\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnull\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/.virtualenvs/universe/lib/python3.9/site-packages/django/db/models/base.py\u001b[0m in \u001b[0;36m__new__\u001b[0;34m(cls, name, bases, attrs, **kwargs)\u001b[0m\n\u001b[1;32m    106\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    107\u001b[0m         \u001b[0;31m# Look for an application configuration to attach the model to.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 108\u001b[0;31m         \u001b[0mapp_config\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mapps\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_containing_app_config\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmodule\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    109\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    110\u001b[0m         \u001b[0;32mif\u001b[0m \u001b[0mgetattr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmeta\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'app_label'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/.virtualenvs/universe/lib/python3.9/site-packages/django/apps/registry.py\u001b[0m in \u001b[0;36mget_containing_app_config\u001b[0;34m(self, object_name)\u001b[0m\n\u001b[1;32m    251\u001b[0m         \u001b[0mReturn\u001b[0m \u001b[0;32mNone\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mthe\u001b[0m \u001b[0mobject\u001b[0m \u001b[0misn\u001b[0m\u001b[0;31m'\u001b[0m\u001b[0mt\u001b[0m \u001b[0;32min\u001b[0m \u001b[0many\u001b[0m \u001b[0mregistered\u001b[0m \u001b[0mapp\u001b[0m \u001b[0mconfig\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    252\u001b[0m         \"\"\"\n\u001b[0;32m--> 253\u001b[0;31m         \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcheck_apps_ready\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    254\u001b[0m         \u001b[0mcandidates\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    255\u001b[0m         \u001b[0;32mfor\u001b[0m \u001b[0mapp_config\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mapp_configs\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalues\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/.virtualenvs/universe/lib/python3.9/site-packages/django/apps/registry.py\u001b[0m in \u001b[0;36mcheck_apps_ready\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m    133\u001b[0m             \u001b[0;31m# INSTALLED_APPS raises a more helpful ImproperlyConfigured\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    134\u001b[0m             \u001b[0;31m# exception.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 135\u001b[0;31m             \u001b[0msettings\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mINSTALLED_APPS\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    136\u001b[0m             \u001b[0;32mraise\u001b[0m \u001b[0mAppRegistryNotReady\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Apps aren't loaded yet.\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    137\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/.virtualenvs/universe/lib/python3.9/site-packages/django/conf/__init__.py\u001b[0m in \u001b[0;36m__getattr__\u001b[0;34m(self, name)\u001b[0m\n\u001b[1;32m     80\u001b[0m         \u001b[0;34m\"\"\"Return the value of a setting and cache it in self.__dict__.\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     81\u001b[0m         \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_wrapped\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0mempty\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 82\u001b[0;31m             \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_setup\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     83\u001b[0m         \u001b[0mval\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mgetattr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_wrapped\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     84\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/.virtualenvs/universe/lib/python3.9/site-packages/django/conf/__init__.py\u001b[0m in \u001b[0;36m_setup\u001b[0;34m(self, name)\u001b[0m\n\u001b[1;32m     61\u001b[0m         \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0msettings_module\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     62\u001b[0m             \u001b[0mdesc\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;34m\"setting %s\"\u001b[0m \u001b[0;34m%\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mname\u001b[0m \u001b[0;32melse\u001b[0m \u001b[0;34m\"settings\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 63\u001b[0;31m             raise ImproperlyConfigured(\n\u001b[0m\u001b[1;32m     64\u001b[0m                 \u001b[0;34m\"Requested %s, but settings are not configured. \"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     65\u001b[0m                 \u001b[0;34m\"You must either define the environment variable %s \"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mImproperlyConfigured\u001b[0m: Requested setting INSTALLED_APPS, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings."
     ]
    }
   ],
   "source": [
    "from django.contrib.auth.models import AbstractUser\n",
    "from django.db import models\n",
    "import uuid\n",
    "\n",
    "# Create your models here.\n",
    "\n",
    "class UserInfo(AbstractUser):\n",
    "    Gender_CHOICES = (\n",
    "        (1, \"男\"),\n",
    "        (2, \"女\"),\n",
    "        (3, \"保密\"),\n",
    "    )\n",
    "\n",
    "    # username = models.CharField(verbose_name='用户名', max_length=32, db_index=True)  # db_index=True 索引,搜索\n",
    "    # email = models.EmailField(verbose_name='邮箱', max_length=32, null=True, blank=True)\n",
    "    uuid = models.UUIDField(verbose_name='用户uuid', default=uuid.uuid4)\n",
    "    mobile_phone = models.CharField(verbose_name='手机号', max_length=11)\n",
    "    password = models.CharField(verbose_name='密码', max_length=32)\n",
    "    avatar = models.ImageField(upload_to='avatar', default='avatar/default.png',\n",
    "                               max_length=200, blank=True, null=True, verbose_name='用户头像')\n",
    "    gender = models.SmallIntegerField(verbose_name='性别', choices=Gender_CHOICES, default=3)\n",
    "    motto = models.CharField(verbose_name='格言', max_length=50, default='')\n",
    "    intro = models.CharField(verbose_name='个人简介', max_length=150, default='')\n",
    "    # follower = models.ManyToManyField('account.UserInfo', through='Follow', related_name='followers')\n",
    "    # 每一名用户对应一个桶\n",
    "    bucket = models.CharField(verbose_name='cos桶', max_length=128)\n",
    "    region = models.CharField(verbose_name='cos区域', max_length=32)\n",
    "    create_datetime = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)\n",
    "\n",
    "    def __str__(self):\n",
    "        return self.username\n",
    "\n",
    "    # 关注我的人\n",
    "    @property\n",
    "    def my_fans(self):\n",
    "        return self.who_follow_me.all()\n",
    "\n",
    "    # 我关注的人\n",
    "    @property\n",
    "    def my_follows(self):\n",
    "        return self.my_follow.all()\n",
    "\n",
    "    def my_friend(self):\n",
    "        for i in self.my_follows:\n",
    "            pass"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "93137280",
   "metadata": {},
   "source": [
    "region，bucket是用户注册括号，为用户创建了独立的区域，桶。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
